{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# langchain笔记"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 配置LANGCHAIN_API_KEY"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import getpass\n",
    "import os\n",
    "\n",
    "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
    "os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用语言模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "pip install -qU langchain-cohere"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import getpass\n",
    "import os\n",
    "os.environ[\"COHERE_API_KEY\"] = getpass.getpass()\n",
    "from langchain_cohere import ChatCohere\n",
    "model = ChatCohere(model=\"command-r\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构造langchain提供的消息体并提问"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.messages import HumanMessage, SystemMessage\n",
    "\n",
    "messages = [\n",
    "    SystemMessage(content=\"Hello! I'm a chatbot. How can I help you today?\"),\n",
    "    HumanMessage(content=\"介绍一下你自己?\"),\n",
    "]\n",
    "result = model.invoke(messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 输出解析器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你好，我是一个智能聊天机器人。我是由一个名为Command的大型语言模型提供的，由一家名为Cohere的公司开发。我的任务是通过提供全面而友好的回答来帮助你。我可以就你感兴趣的任何主题与你交谈，并努力为你提供有用的信息。我希望我们能有一个愉快的聊天。请随时告诉我你想问什么，我会尽我所能地帮助你。'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_core.output_parsers import StrOutputParser\n",
    "parser = StrOutputParser()\n",
    "parser.invoke(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构建模型-->输出解析器的问答链"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你好，我是一个智能聊天机器人。我是由一个名为Command的大型语言模型支持的。我可以帮助用户以多种方式进行交谈，并提供有用的信息和答案。我可以讨论各种各样的题目，例如科学、技术、音乐、体育等等。我还可以根据要求提供更多的信息和细节。此外，我还可以帮助用户完成一些任务，例如寻找餐厅、推荐电影等等。我很乐意帮助你，让我们好好聊聊吧！'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain = model | parser\n",
    "chain.invoke(messages)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Prompt Templates"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[SystemMessage(content='Translate the following into English:'),\n",
       " HumanMessage(content='你好')]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "\n",
    "system_template = \"Translate the following into {language}:\"\n",
    "prompt_template = ChatPromptTemplate.from_messages([\n",
    "    (\"system\", system_template), (\"user\", \"{text}\")\n",
    "])\n",
    "result = prompt_template.invoke({\"language\": \"English\", \"text\": \"你好\"})\n",
    "\n",
    "# result\n",
    "\n",
    "result.to_messages()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构建 prompt | model | parser 链"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello!'"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain = prompt_template | model | parser\n",
    "chain.invoke({\"language\": \"English\", \"text\": \"你好\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用LangServe服务"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "pip install \"langserve[all]\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "要为我们的应用程序创建服务器，我们将创建一个serve.py文件。这将包含我们为应用程序提供服务的逻辑。它由三部分组成：\n",
    "1.们刚刚在上面建立的链条的定义\n",
    "2.FastAPI应用程序\n",
    "3.为链提供服务的路由的定义：langserve.add_routes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "from fastapi import FastAPI\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "from langchain_core.output_parsers import StrOutputParser\n",
    "from langchain_cohere import ChatCohere\n",
    "from langserve import add_routes\n",
    "\n",
    "# 1.Create prompt template\n",
    "system_template = \"Translate the following into {language}:\"\n",
    "prompt_template = ChatPromptTemplate.from_messages(\n",
    "    [(\"system\", system_template), (\"user\", \"{text}\")]\n",
    ")\n",
    "\n",
    "# 2.Create model\n",
    "model = ChatCohere(model=\"command-r\")\n",
    "\n",
    "# 3.Create parser\n",
    "parser = StrOutputParser()\n",
    "\n",
    "# 4.Create chain\n",
    "chain = prompt_template | model | parser\n",
    "\n",
    "# 5.Create app\n",
    "app = FastAPI(\n",
    "    title=\"langChain Sserver\",\n",
    "    version=\"1.0\",\n",
    "    description=\"A simple langChain API server\",\n",
    ")\n",
    "\n",
    "# 6.Adding chain routes\n",
    "add_routes(\n",
    "    app,\n",
    "    chain,\n",
    "    path=\"/chain\",\n",
    ")\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    import uvicorn\n",
    "\n",
    "    uvicorn.run(app, host=\"localhost\", port=8000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 运行\n",
    "python serve.py\n",
    "we should see our chain being served at http://localhost:8000."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Playground\n",
    "每个LangServe服务都带有一个简单的内置用户界面，用于配置和调用应用程序，并具有流式输出和中间步骤的可见性。前往http://localhost:8000/chain/playground/尝试一下！传入与以前相同的输入-{\"language\": \"italian\", \"text\": \"hi\"}-它应该和以前一样响应。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Client\n",
    "现在让我们设置一个客户端，以便以编程方式与我们的服务进行交互。我们可以使用[langserve.RemoteRunnable](/docs/langserve/#client)轻松地做到这一点。使用它，我们可以像运行客户端一样与服务链进行交互。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Ciao!'"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langserve import RemoteRunnable\n",
    "\n",
    "remote_chain = RemoteRunnable(\"http://localhost:8000/chain/\")\n",
    "remote_chain.invoke({\"language\": \"italian\", \"text\": \"hi\"})"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchain-demo",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
